package br.ufes.cwtools.gw.android.connection_service;

import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public abstract class ConnectionServiceConnection implements ServiceConnection {
	private static final String LOG_TAG = "ConnectionServiceConnection";

	private IConnectionService mConnectionService = null;
	private String mRequestor = "";
	private static int currentId = 1;
	
	private static int getNextId() {
		return currentId++;
	}
	
	public static String generateId() {
		return "" + getNextId();
	}
	
	private IConnectionServiceCallback mCallback = new IConnectionServiceCallback.Stub() {
		@Override
		public void requestFinished(String id, String filePath) throws RemoteException {
			Log.d(LOG_TAG, "Callback recebido para uma requisição.");
			onRequestFinished(id, filePath);
		}
	};
	
	/**
	 * @param requestor identify the requests made by this instance (usually the class name) 
	 */
	public ConnectionServiceConnection(String requestor) {
		mRequestor = requestor;
	}
	
	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		mConnectionService = IConnectionService.Stub.asInterface(service);
		onServiceConnected();
	}
	
	@Override
	public void onServiceDisconnected(ComponentName name) {
		mConnectionService = null;
	}

	/**
	 * @return the remote object interface.
	 * @throws NotConnectedException if the service is not connected
	 */
	private IConnectionService getConnectionService()
			throws NotConnectedException {
		if (mConnectionService == null) throw new NotConnectedException();
		else return mConnectionService;
	}
	
	public void setLoginData(String url, String user, String pass) throws NotConnectedException, RemoteException{
		getConnectionService().setLoginData(url, user, pass);
	}
	
	public int registerGetRequest(String url, String id, boolean allowCache)
			throws RemoteException, NotConnectedException {
		return getConnectionService().registerGetRequest(url, mRequestor, id, allowCache, mCallback);
	}
	
	public int registerPostRequest(String url, String id, Bundle stringParts, Bundle fileParts)
			throws NotConnectedException, RemoteException {
		return getConnectionService().registerPostRequest(url, mRequestor, id, stringParts, fileParts, mCallback);
	}
	
	public void unregister(String id)
			throws RemoteException, NotConnectedException {
		getConnectionService().unregister(mRequestor, id);
	}
	
	public void unregisterAll()
			throws RemoteException, NotConnectedException {
		getConnectionService().unregisterAll(mRequestor);
	}
	
	/**
	 * Called when a download has been finished. 
	 * @param filePath to the downloaded file
	 */
	public abstract void onRequestFinished(String id, String filePath);
	
	public abstract void onServiceConnected();
	
	/**
	 * Indicates that the service was not connected as expected.
	 */
	public class NotConnectedException extends RemoteException {
		private static final long serialVersionUID = 1L;
		// Intentionally left empty.
	}
}
